﻿using System;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Text;
using System.Linq;

namespace ProductCollector {
    public class AeiomedSearcher : ISiteSearcher {
        private const string URL_ALL = "http://www.agindustries.com/index.php?route=product/search&filter_name={0}&filter_description=true&filter_sub_category=true&page={1}";

        private const string URL_CATEGORY =
            "http://www.agindustries.com/index.php?route=product/search&filter_name={0}&filter_category_id={1}&filter_sub_category=true&filter_description=true&page={2}";

        private const string HOME_URL = "http://www.agindustries.com";
        public IList<Product> Search(SearchCriteria criteria) {
            var web = new HtmlWeb();
            string url = criteria.AllCategory ? URL_ALL : URL_CATEGORY;
            url = criteria.AllCategory
                      ? string.Format(url, criteria.SearchValue, criteria.CurrentPageIndex)
                      : string.Format(url, criteria.SearchValue, criteria.Category, criteria.CurrentPageIndex);
            HtmlDocument doc = web.Load(url);
            var gridNode = doc.DocumentNode.SelectNodes("//*[contains(@class,'product-grid')]");
            bool findByGrid = gridNode != null;
            if (gridNode == null) {
                gridNode = doc.DocumentNode.SelectNodes("//*[contains(@class,'product-list')]");
            }
            var content = gridNode == null ? null : gridNode.FirstOrDefault();
            return findByGrid?
                FindProductByGrid(content) :
                FindProductByList(content);
        }

        public int CountProduct(SearchCriteria criteria) {
            var web = new HtmlWeb();
            string url = criteria.AllCategory ? URL_ALL : URL_CATEGORY;
            url = criteria.AllCategory
                      ? string.Format(url, criteria.SearchValue, criteria.CurrentPageIndex)
                      : string.Format(url, criteria.SearchValue, criteria.Category, criteria.CurrentPageIndex);
            HtmlDocument doc = web.Load(url);
            var gridNode = doc.DocumentNode.SelectNodes("//*[contains(@class,'product-grid')]");
            if (gridNode == null) {
                gridNode = doc.DocumentNode.SelectNodes("//*[contains(@class,'product-list')]");
            }
            return gridNode == null ? 0 :
            gridNode[0].ChildNodes.Count;
        }
        public List<Product> FindProductByList(HtmlNode node) {
            if (node == null) {
                return null;
            }
            var results = new List<Product>(node.ChildNodes.Count);
            var pNodes = node.SelectNodes("div");
            foreach (HtmlNode productNode in pNodes) {
                //if (left != null) {
                    Product p = GetProductFromNode(productNode);
                    if (p != null) {
                        results.Add(p);
                    }
                //}
            }
            return results;
        }
        private Product GetProductFromNode(HtmlNode productNode) {
            Product product = new Product();
            HtmlNode img = productNode.SelectSingleNode("./div[contains(@class,'image')]/a");
            if (img != null) {
                product.OriginalUrl = img.GetAttributeValue("href", HOME_URL);
            }
            HtmlNode imgNode = productNode.SelectSingleNode("./div[contains(@class,'image')]/a/img");
            if (imgNode != null) {
                product.ThumbImg = imgNode.GetAttributeValue("src", HOME_URL);
            }
            HtmlNode nameNode = productNode.SelectSingleNode("./div[contains(@class,'name')]/a");
            if (nameNode != null) {
                product.ProductName = nameNode.InnerText.Trim();
            }
            HtmlNode attrName = productNode.SelectSingleNode("./div[contains(@class,'attribute_name')]");
            StringBuilder desc = new StringBuilder();
            if (attrName != null) {
                desc.Append(attrName.InnerHtml.Trim());
            }
            HtmlNode descNode = productNode.SelectSingleNode("./div[contains(@class,'description')]");
            if (descNode != null) {
                desc.AppendLine(descNode.InnerHtml.Trim());
            }
            product.Description = desc.ToString();
            return product;
        }
        public List<Product> FindProductByGrid(HtmlNode node) {
            if (node == null) {
                return null;
            }
            var results = new List<Product>(node.ChildNodes.Count);
            foreach (HtmlNode productNode in node.ChildNodes) {
                HtmlNode left = productNode.SelectSingleNode("/div[contains(@class,'left')]");
                if (left != null) {
                    Product p = GetProductFromNode(left);
                    if (p != null) {
                        results.Add(p);
                    }
                }
            }
            return results;
        }
    }
}
